﻿namespace Smark.Core
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Globalization;
    using System.IO;
    using System.Net;
    using System.Net.Mail;
    using System.Net.Mime;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Runtime.Remoting.Messaging;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Security.Cryptography;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Xml.Serialization;

    public class Functions
    {
        private static object mLockSerializer = new object();
        private static Random mRan = new Random();
        private static string mRanSeed = "abcdefghijklmnopqrstuvwxyz";
        private static Dictionary<string, Type> mTypeTable = new Dictionary<string, Type>();
        private static Dictionary<string, XmlSerializer> mXmlSerializerTable = new Dictionary<string, XmlSerializer>();

        private Functions()
        {
        }

        public static void Action(AsyncDelegate handler)
        {
            handler.BeginInvoke(delegate (IAsyncResult ac) {
                GetEndHandler<AsyncDelegate>(ac).EndInvoke(ac);
            }, null);
        }

        public static void Action<T>(T t, AsyncDelegate<T> handler)
        {
            handler.BeginInvoke(t, delegate (IAsyncResult ac) {
                GetEndHandler<AsyncDelegate<T>>(ac).EndInvoke(ac);
            }, null);
        }

        public static void Action<T, T1>(T t, T1 t1, AsyncDelegate<T, T1> handler)
        {
            handler.BeginInvoke(t, t1, delegate (IAsyncResult ac) {
                GetEndHandler<AsyncDelegate<T, T1>>(ac).EndInvoke(ac);
            }, null);
        }

        public static void Action<T, T1, T2>(T t, T1 t1, T2 t2, AsyncDelegate<T, T1, T2> handler)
        {
            handler.BeginInvoke(t, t1, t2, delegate (IAsyncResult ac) {
                GetEndHandler<AsyncDelegate<T, T1, T2>>(ac).EndInvoke(ac);
            }, null);
        }

        public static void Action<T, T1, T2, T3>(T t, T1 t1, T2 t2, T3 t3, AsyncDelegate<T, T1, T2, T3> handler)
        {
            handler.BeginInvoke(t, t1, t2, t3, delegate (IAsyncResult ac) {
                GetEndHandler<AsyncDelegate<T, T1, T2, T3>>(ac).EndInvoke(ac);
            }, null);
        }

        public static void Action<T, T1, T2, T3, T4>(T t, T1 t1, T2 t2, T3 t3, T4 t4, AsyncDelegate<T, T1, T2, T3, T4> handler)
        {
            handler.BeginInvoke(t, t1, t2, t3, t4, delegate (IAsyncResult ac) {
                GetEndHandler<AsyncDelegate<T, T1, T2, T3, T4>>(ac).EndInvoke(ac);
            }, null);
        }

        public static string AppSettingValue(string name)
        {
            return ConfigurationSettings.AppSettings[name];
        }

        public static T AppSettingValue<T>(string name)
        {
            return (T) Convert.ChangeType(AppSettingValue(name), typeof(T));
        }

        public static bool AppSettingValue(string name, out string value)
        {
            value = ConfigurationSettings.AppSettings[name];
            return !string.IsNullOrEmpty(value);
        }

        public static object DeserializeObject(byte[] pBytes)
        {
            return DeserializeObject(pBytes, pBytes.Length);
        }

        public static object DeserializeObject(byte[] pBytes, int count)
        {
            return DeserializeObject(pBytes, 0, count);
        }

        public static object DeserializeObject(byte[] pBytes, int index, int count)
        {
            object obj2 = null;
            if (pBytes == null)
            {
                return obj2;
            }
            using (MemoryStream stream = new MemoryStream(pBytes, index, count))
            {
                stream.Position = 0L;
                obj2 = new BinaryFormatter().Deserialize(stream);
                stream.Close();
                return obj2;
            }
        }

        public static object DeserializeObjectByString(string text)
        {
            return DeserializeObject(Convert.FromBase64String(text));
        }

        public static long DirSize(DirectoryInfo d)
        {
            long num = 0L;
            foreach (FileInfo info in d.GetFiles())
            {
                num += info.Length;
            }
            foreach (DirectoryInfo info2 in d.GetDirectories())
            {
                num += DirSize(info2);
            }
            return num;
        }

        public static IEnumerable<T> Find<T>(IEnumerable source, EventFindHandler<T> handler)
        {
            List<T> list = new List<T>();
            if (source != null)
            {
                foreach (object obj2 in source)
                {
                    if (handler((T) obj2))
                    {
                        list.Add((T) obj2);
                    }
                }
            }
            return list;
        }

        public static int GetByteCount(string hexString)
        {
            int num = 0;
            for (int i = 0; i < hexString.Length; i++)
            {
                char c = hexString[i];
                if (IsHexDigit(c))
                {
                    num++;
                }
            }
            if ((num % 2) != 0)
            {
                num--;
            }
            return (num / 2);
        }

        public static byte[] GetBytes(string hexString, out int discarded)
        {
            discarded = 0;
            string str = "";
            for (int i = 0; i < hexString.Length; i++)
            {
                char c = hexString[i];
                if (IsHexDigit(c))
                {
                    str = str + c;
                }
                else
                {
                    discarded++;
                }
            }
            if ((str.Length % 2) != 0)
            {
                discarded++;
                str = str.Substring(0, str.Length - 1);
            }
            int num2 = str.Length / 2;
            byte[] buffer = new byte[num2];
            int num3 = 0;
            for (int j = 0; j < buffer.Length; j++)
            {
                string hex = new string(new char[] { str[num3], str[num3 + 1] });
                buffer[j] = HexToByte(hex);
                num3 += 2;
            }
            return buffer;
        }

        private static T GetEndHandler<T>(IAsyncResult e)
        {
            return (T) ((AsyncResult) e).AsyncDelegate;
        }

        public static T[] GetFieldAttributes<T>(FieldInfo field, bool inhert) where T: Attribute
        {
            return (T[]) field.GetCustomAttributes(typeof(T), inhert);
        }

        public static T[] GetMethodAttributes<T>(MethodInfo mi, bool inhert) where T: Attribute
        {
            return (T[]) mi.GetCustomAttributes(typeof(T), inhert);
        }

        public static T[] GetParemeterAttributes<T>(ParameterInfo pi, bool inhert) where T: Attribute
        {
            return (T[]) pi.GetCustomAttributes(typeof(T), inhert);
        }

        public static string GetPath(Assembly assemble)
        {
            return (Path.GetDirectoryName(assemble.Location) + @"\");
        }

        public static string GetPath(string path)
        {
            if (path.Substring(path.Length - 1, 1) != @"\")
            {
                return (path + @"\");
            }
            return path;
        }

        public static T[] GetPropertyAttributes<T>(PropertyInfo pi, bool inhert) where T: Attribute
        {
            return (T[]) pi.GetCustomAttributes(typeof(T), inhert);
        }

        public static string GetRanString(int length)
        {
            string str = "";
            for (int i = 0; i < length; i++)
            {
                str = str + mRanSeed.Substring(mRan.Next(0x19), 1);
            }
            return str;
        }

        public static Type GetType(string fullname)
        {
            string[] strArray = fullname.Split(new char[] { ',' });
            return Assembly.Load(strArray[1]).GetType(strArray[0], true);
        }

        public static T[] GetTypeAttributes<T>(Type type, bool inhert) where T: Attribute
        {
            return (T[]) type.GetCustomAttributes(typeof(T), inhert);
        }

        public static Type GetTypeByCache(string fullname)
        {
            if (!mTypeTable.ContainsKey(fullname))
            {
                lock (mTypeTable)
                {
                    if (!mTypeTable.ContainsKey(fullname))
                    {
                        Type type = Type.GetType(fullname);
                        mTypeTable.Add(fullname, type);
                    }
                }
            }
            return mTypeTable[fullname];
        }

        public static XmlSerializer GetXmlSerializer(Type type, XmlRootAttribute xRoot)
        {
            string key = type.FullName + ((xRoot != null) ? xRoot.ElementName : "");
            if (!mXmlSerializerTable.ContainsKey(key))
            {
                lock (mLockSerializer)
                {
                    if (!mXmlSerializerTable.ContainsKey(key))
                    {
                        if (xRoot != null)
                        {
                            mXmlSerializerTable.Add(key, new XmlSerializer(type, xRoot));
                        }
                        else
                        {
                            mXmlSerializerTable.Add(key, new XmlSerializer(type));
                        }
                    }
                }
            }
            return mXmlSerializerTable[key];
        }

        private static byte HexToByte(string hex)
        {
            if ((hex.Length > 2) || (hex.Length <= 0))
            {
                throw new ArgumentException("hex must be 1 or 2 characters in length");
            }
            return byte.Parse(hex, NumberStyles.HexNumber);
        }

        public static bool InHexFormat(string hexString)
        {
            foreach (char ch in hexString)
            {
                if (!IsHexDigit(ch))
                {
                    return false;
                }
            }
            return true;
        }

        public static void Is<T>(object obj, AsyncDelegate<T> handler)
        {
            if (obj is T)
            {
                handler((T) obj);
            }
        }

        public static bool IsDateTime(object value)
        {
            return IsDateTime(value.ToString());
        }

        public static bool IsDateTime(string value)
        {
            DateTime time;
            return DateTime.TryParse(value, out time);
        }

        public static bool IsEmpty(Array value)
        {
            if ((value != null) && (value.Length != 0))
            {
                return false;
            }
            return true;
        }

        public static bool IsEmpty(IDictionary value)
        {
            if ((value != null) && (value.Count != 0))
            {
                return false;
            }
            return true;
        }

        public static bool IsEmpty(IList value)
        {
            if ((value != null) && (value.Count != 0))
            {
                return false;
            }
            return true;
        }

        public static bool IsEmpty(DateTime value)
        {
            return (value == DateTime.MinValue);
        }

        public static bool IsEmpty(string value)
        {
            return string.IsNullOrEmpty(value);
        }

        public static bool IsHexDigit(char c)
        {
            int num2 = Convert.ToInt32('A');
            int num3 = Convert.ToInt32('0');
            c = char.ToUpper(c);
            int num = Convert.ToInt32(c);
            return (((num >= num2) && (num < (num2 + 6))) || ((num >= num3) && (num < (num3 + 10))));
        }

        public static bool IsInt(object value)
        {
            return IsInt(value.ToString());
        }

        public static bool IsInt(string value)
        {
            int num;
            return int.TryParse(value, out num);
        }

        public static bool IsNumber(object value)
        {
            return IsNumber(value.ToString());
        }

        public static bool IsNumber(string value)
        {
            return Regex.IsMatch(value, @"^(\d+|(\d+\.\d+)+)$", RegexOptions.IgnoreCase);
        }

        public static T[] ListToArray<T>(IList list)
        {
            T[] array = new T[list.Count];
            list.CopyTo(array, 0);
            return array;
        }

        public static string MD5Crypto(string text)
        {
            return ToString(MD5Crypto(Encoding.UTF8.GetBytes(text)));
        }

        public static byte[] MD5Crypto(byte[] data)
        {
            MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
            return provider.ComputeHash(data);
        }

        public void SendMail(string from, string password, string title, string body, bool ishtml, IEnumerable<string> tos, IEnumerable<string> asttachments)
        {
            MailMessage message = new MailMessage {
                From = new MailAddress(from)
            };
            foreach (string str in tos)
            {
                message.To.Add(str);
            }
            if (asttachments != null)
            {
                foreach (string str2 in asttachments)
                {
                    Attachment item = new Attachment(str2, "application/octet-stream");
                    ContentDisposition contentDisposition = item.ContentDisposition;
                    contentDisposition.CreationDate = System.IO.File.GetCreationTime(str2);
                    contentDisposition.ModificationDate = System.IO.File.GetLastWriteTime(str2);
                    contentDisposition.ReadDate = System.IO.File.GetLastAccessTime(str2);
                    message.Attachments.Add(item);
                }
            }
            message.Subject = title;
            message.Body = body;
            message.BodyEncoding = Encoding.UTF8;
            message.IsBodyHtml = ishtml;
            message.Priority = MailPriority.Normal;
            new SmtpClient { Credentials = new NetworkCredential(message.From.Address, password), DeliveryMethod = SmtpDeliveryMethod.Network, Host = "smtp." + message.From.Host }.Send(message);
        }

        public static byte[] SerializeObject(object pObj)
        {
            if (pObj == null)
            {
                return null;
            }
            using (MemoryStream stream = new MemoryStream())
            {
                new BinaryFormatter().Serialize(stream, pObj);
                stream.Position = 0L;
                byte[] buffer = new byte[stream.Length];
                stream.Read(buffer, 0, buffer.Length);
                stream.Close();
                return buffer;
            }
        }

        public static string SerializeObjectToString(object pOjb)
        {
            return Convert.ToBase64String(SerializeObject(pOjb));
        }

        public static string ToString(byte[] bytes)
        {
            string str = "";
            for (int i = 0; i < bytes.Length; i++)
            {
                str = str + bytes[i].ToString("X2");
            }
            return str;
        }

        public static string ToString(Encoding coding, byte[] data, int index, int count)
        {
            return coding.GetString(data, index, count);
        }

        public static string UpperDate(DateTime time)
        {
            int num;
            string str = "〇一二三四五六七八九";
            StringBuilder builder = new StringBuilder();
            string[] strArray = new string[] { time.Year.ToString(), time.Month.ToString("00"), time.Day.ToString("00") };
            for (int i = 0; i < strArray[0].Length; i++)
            {
                num = int.Parse(strArray[0].Substring(i, 1));
                builder.Append(str.Substring(num, 1));
            }
            builder.Append("年");
            for (int j = 0; j < strArray[1].Length; j++)
            {
                num = int.Parse(strArray[1].Substring(j, 1));
                if (j == 0)
                {
                    if (num > 0)
                    {
                        builder.Append("十");
                    }
                }
                else if (num > 0)
                {
                    builder.Append(str.Substring(num, 1));
                }
            }
            builder.Append("月");
            for (int k = 0; k < strArray[2].Length; k++)
            {
                num = int.Parse(strArray[2].Substring(k, 1));
                if (k == 0)
                {
                    if (num > 0)
                    {
                        if (num > 1)
                        {
                            builder.Append(str.Substring(num, 1));
                        }
                        builder.Append("十");
                    }
                }
                else if (num > 0)
                {
                    builder.Append(str.Substring(num, 1));
                }
            }
            builder.Append("日");
            return builder.ToString();
        }

        public static string AssemblyPath
        {
            get
            {
                return (Path.GetDirectoryName(typeof(Functions).Assembly.Location) + @"\");
            }
        }
    }
}

